package com.qf.kele02.controller;

import cn.hutool.crypto.digest.DigestUtil;
import com.baomidou.kaptcha.Kaptcha;
import com.qf.kele02.entity.User;
import com.qf.kele02.service.UserSevice;
import com.qf.kele02.service.impl.UserServicePlusImp;
import com.qf.kele02.utils.Constants;
import com.qf.kele02.vo.ResultVo;
import com.qf.kele02.vo.TableVo;
import com.qf.kele02.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/user")
@Slf4j   // 添加该注解后，可以使用 log对象进行日志的打印
public class UserController {
	@Autowired
	Kaptcha kaptcha;

	@Qualifier(value="userServicePlusImp")
	@Autowired
	UserSevice userSevice ;

	@PostMapping("/login")
	public ResultVo login( String username,String password,String capchar,String autologin,
	                       HttpServletResponse response,HttpSession session ) {

		log.info( "username={},password={},capchar={}",username,password,capchar );

		//1. 处理验证码是否正确


		if(!kaptcha.validate( capchar )) {
			return new ResultVo( Constants.FAIL_CODE,"验证码错误" );
		}

		//2. 调用service层的方法进行登录验证
		User user=userSevice.login( username,password );
		log.info( "调用service层方法校验用户密码，返回的user对象={}",user );

		//3. 如果user不为null，则代表登录成功，如果user为null，则登录失败
		if(user!=null) {

			// 如果用户登录成功，把user对象存入session
			session.setAttribute( Constants.SESSION_USER_KEY,user );

			if("on".equals( autologin )) {
				// 生成用于免登录的cookie ，cookie中的信息包含用户名和密码
				final String md5password=DigestUtil.md5Hex( password );
				String cookievalue=username+"-"+md5password;
				final Cookie cookie=new Cookie( Constants.USER_TOKEN,cookievalue );
				cookie.setPath( "/" );  // 设置cookie为该域的顶级cookie
				cookie.setMaxAge( 60*60*24*14 );  // 两周有效期
				log.debug( "用户设置免登录,cookie={}",cookievalue );
				response.addCookie( cookie );
			}


			return new ResultVo( Constants.SUCCESS_CODE,"登录成功" );

		}else {
			return new ResultVo( Constants.FAIL_CODE,"登录失败" );
		}


	}

	/**
	 * 用户注册接口，该接口接收的是文件上传请求
	 *
	 * @param userVo
	 * @param session
	 * @return
	 */
	@PostMapping("/regist")
	public ResultVo regist( UserVo userVo,HttpSession session ) throws IOException {

		log.info( "用户注册请求处理, userVo={}",userVo );

		//1. 处理验证码是否正确
		if(!kaptcha.validate( userVo.getCapchar( ) )) {
			return new ResultVo( Constants.FAIL_CODE,"验证码错误" );
		}


		//2. 调用service层方法完成注册的业务逻辑
		final String realPath=Constants.RealPath;

		ResultVo resultVo=userSevice.regist( userVo,realPath );

		return resultVo;
	}

	/**
	 * 获取登录用户的用户名
	 *
	 * @param session
	 * @return
	 */
	@GetMapping("/currentuser")
	public ResultVo getCurrentUser( HttpSession session ) {

		//从session中获取当前登录用户 的用户名
		final User user=(User) session.getAttribute( Constants.SESSION_USER_KEY );
		log.debug( "获取当前登录用户，user={}",user );
		if(user!=null) {

			return new ResultVo( Constants.SUCCESS_CODE,"获取登录用户成功",user.getName( ) );
		}else {
			return new ResultVo( Constants.FAIL_CODE,"获取登录用户失败" );
		}

	}

	/**
	 * 获取当前登录用户的头像
	 */
	@GetMapping("/pic")
	public void getPic( HttpSession session,HttpServletResponse response ) throws IOException {
		//从session中获取当前登录用户 的用户名
		final User user=(User) session.getAttribute( Constants.SESSION_USER_KEY );
		if(user!=null) {

			final String photopath=user.getPhotopath( );

			final String fileDir=Constants.RealPath;

			final String finalFilepath=fileDir+File.separator+photopath;
			log.debug( "获取登录用户的头像，文件路径为={}",finalFilepath );
			// 把图片文件响应给浏览器
			IOUtils.copy( new FileInputStream( finalFilepath ),response.getOutputStream( ) );

		}else {

			return;

		}
	}


	@GetMapping("/checkusername")
	public ResultVo checkusername( String username ) {
		// 调用service层检查用户名是否存在
		ResultVo resultVo=userSevice.checkUsername( username );
		log.debug( "检查用户名是否存在，username={},resultVo={}",username,resultVo );
		return resultVo;

	}

	/**
	 * 用户数据表格分页查询接口
	 *
	 * @param page  页号
	 * @param limit 页大小
	 * @return
	 */
	@GetMapping("/getAllUsers")
	public TableVo< User > getAllUser( Integer page,Integer limit ) {

		log.debug( "分页查询用户，page={},limit={}",page,limit );

		TableVo tableVo=userSevice.getAllUserByPage( page,limit );

		log.debug( "查询到的结果为，tableVo={}",tableVo );

		return tableVo;
	}


	/**
	 * 使用分页插件实现
	 *
	 * @param page
	 * @param limit
	 * @return
	 */
	@GetMapping("/getUserByPagehelper")
	public TableVo< User > getUserByPagehelper( Integer page,Integer limit ) {

		log.debug( "分页查询用户，page={},limit={}",page,limit );

		TableVo tableVo=userSevice.getUserByPagehelper( page,limit );

		log.debug( "查询到的结果为，tableVo={}",tableVo );

		return tableVo;
	}


	/**
	 * 添加用户接口
	 *
	 * @param user
	 * @return
	 */
	@PostMapping("/add")
	public ResultVo add( User user ) {

		log.debug( "接收到参数，user={}",user );

		ResultVo resultVo=userSevice.addUser( user );
		log.debug( "新增结果为,resultVo={}",resultVo );
		return resultVo;
	}


	/**
	 * @param idarray
	 * @return
	 * @RequestParam 这个注解可以处理方法参数名和请求参数名不一致的情况
	 */
	@RequestMapping("/del")
	public ResultVo del( @RequestParam("ids") List< Integer > idarray ) {

		log.debug( "收到参数:ids={}",idarray );

		ResultVo resultVo=userSevice.deleteUserByIds( idarray );

		log.debug( "删除结果为,resultVo={}",resultVo );
		return resultVo;
	}


	@PostMapping("/update")
	public ResultVo update( User user ) {

		log.debug( "收到参数,user={}",user );
		ResultVo resultVo=userSevice.updateUser( user );
		log.debug( "修改结果为,resultVo={}",resultVo );
		return resultVo;
	}


	/**
	 * 带查询条件的数据表格接口
	 *
	 * @param page
	 * @param limit
	 * @param userVo
	 * @return
	 */
	@GetMapping("/getUsersByContdition")
	public TableVo< User > getUsersByContdition( Integer page,Integer limit,UserVo userVo ) {

		log.debug( "收到参数,page={},limit={},userVo={}",page,limit,userVo );

		TableVo< User > result=userSevice.getUsersByContdition( page,limit,userVo );

		return result;
	}

	@GetMapping("/export")
	public TableVo< String > export( ) throws IOException, IllegalAccessException, ClassNotFoundException {

		//1. 调用service层的方法进行数据导出，生成文件,返回文件名
		String filename=userSevice.export( );

		log.info( "返回的文件名,name=${}",filename );
		List< String > list=new ArrayList<>( );
		list.add( filename );
		//2. 返回包含文件名的 resultVO
		return new TableVo< String >( 0,"导出文件成功",list.size( ),list );

	}

	@PostMapping("/insert")
	public TableVo< User > insert( MultipartFile source ) throws IOException, IllegalAccessException, ClassNotFoundException, InstantiationException, ParseException {

		log.info( "收到的文件",source );


		//调用service层的方法
		TableVo< User > tableVo=userSevice.insert( source );


		return tableVo;
	}


	@RequestMapping("/notnull")
	public TableVo< User > isCorrect( @Valid User user ) throws IOException, IllegalAccessException, ClassNotFoundException, InstantiationException, ParseException {

		log.info( "收到的文件",user );

		return null;
	}


	@RequestMapping("/deleteHead")
	public ResultVo deleteHead( ) throws IOException, IllegalAccessException, ClassNotFoundException, InstantiationException, ParseException {

		ResultVo resultVo=userSevice.deleteHead( );

		return resultVo;
	}

}
